﻿/*
输入：
10 10
1 0 0 0 1 0 0 0 0 0
1 1 0 1 1 0 1 0 1 0
1 0 1 1 1 0 0 1 0 0
1 0 1 1 0 0 0 1 0 0
1 1 1 1 1 0 0 1 0 0
1 0 1 1 0 0 0 1 0 0
1 1 1 0 0 1 1 0 1 1
0 1 1 0 1 1 0 0 0 1
0 0 0 1 0 0 0 0 1 1
1 1 1 0 1 0 0 0 0 0
输出：
32
*/
// N行M列
string[] NMArr = Console.ReadLine().Split(" ");
int N = int.Parse(NMArr[0]);
int M = int.Parse(NMArr[1]);

// 地图
int[,] map = new int[N, M];
Dictionary<int, int> area = new Dictionary<int, int>(); // 记录面积
for (int i = 0; i < N; i++)
{
    string[] line = Console.ReadLine().Split(" ");
    for (int j = 0; j < M; j++)
    {
        map[i, j] = int.Parse(line[j]);
    }
}

// 广度优先搜索
int bfs(int[,] map, int ki, int kj, int fill)
{
    int s = 0; // 记录面积
    Queue<(int, int)> queue = new Queue<(int, int)>();
    queue.Enqueue((ki, kj));

    while (queue.Count > 0)
    {
        (int i, int j) = queue.Dequeue();

        if (map[i, j] == fill) continue;
        map[i, j] = fill;
        s++;
        
        // 向右
        if (j + 1 < map.GetLength(1) && map[i, j + 1] == 1)
        {
            queue.Enqueue((i, j + 1));
        }
        // 向下
        if (i + 1 < map.GetLength(0) && map[i + 1, j] == 1)
        {
            queue.Enqueue((i + 1, j));
        }
        // 向左
        if (j > 0 && map[i, j - 1] == 1)
        {
            queue.Enqueue((i, j - 1));
        }
        // 向上
        if (i > 0 && map[i - 1, j] == 1)
        {
            queue.Enqueue((i - 1, j));
        }
            
    }
    return s;
}

// 修改地图
int index = 2;
for (int i = 0; i < N; i++)
{
    for (int j = 0; j < M; j++)
    {
        if (map[i, j] == 1)
        {
            int areaTemp = bfs(map, i, j, index);
            area[index] = areaTemp;
            index++;
        }
    }
}

// 统计最大值
int max = 1;
if (area.Count > 0)
{
    max = area[2];
}
else
{
    Console.WriteLine(max);
    return;
}

HashSet<int> hset = new HashSet<int>();
for (int i = 0; i < N; i++)
{
    for (int j = 0; j < M; j++)
    {
        if (map[i, j] == 0)
        {
            int temp = 1;
            hset.Clear();
            // 向右
            if (j + 1 < map.GetLength(1) && map[i, j + 1] != 0)
            {
                hset.Add(map[i, j + 1]);
            }
            // 向下
            if (i + 1 < map.GetLength(0) && map[i + 1, j] != 0)
            {
                hset.Add(map[i + 1, j]);
            }
            // 向左
            if (j > 0 && map[i, j - 1] != 0)
            {
                hset.Add(map[i, j - 1]);
            }
            // 向上
            if (i > 0 && map[i - 1, j] != 0)
            {
                hset.Add(map[i - 1, j]);
            }

            foreach (int k in hset)
            {
                temp += area[k];
            }
            max = temp > max ? temp : max;
        }
    }
}
Console.WriteLine(max);